package com.itmumu.miniwechat.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itmumu.miniwechat.common.exception.BusinessException;
import com.itmumu.miniwechat.common.utils.ContextUtil;
import com.itmumu.miniwechat.user.domain.dto.UserContactApplyDto;
import com.itmumu.miniwechat.user.domain.enums.*;
import com.itmumu.miniwechat.user.domain.po.User;
import com.itmumu.miniwechat.user.domain.po.UserContact;
import com.itmumu.miniwechat.user.domain.po.UserContactApply;
import com.itmumu.miniwechat.user.domain.vo.request.UserContactApplyQuery;
import com.itmumu.miniwechat.user.domain.vo.response.PageResultVo;
import com.itmumu.miniwechat.user.domain.vo.response.UserContactVo;
import com.itmumu.miniwechat.user.mapper.UserContactApplyMapper;
import com.itmumu.miniwechat.user.service.UserContactApplyService;
import com.itmumu.miniwechat.user.service.UserContactService;
import com.itmumu.miniwechat.user.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.Instant;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

/**
* @author admin
* @description 针对表【user_contact_apply(联系人申请表)】的数据库操作Service实现
* @createDate 2024-12-30 19:37:14
*/
@Service
public class UserContactApplyServiceImpl extends ServiceImpl<UserContactApplyMapper, UserContactApply>
    implements UserContactApplyService {

    @Autowired
    private UserContactService userContactService;

    @Autowired
    private UserService userService;



    /**
     * 用户申请添加好友
     *
     * @param applyDto
     */
    @Override
    public void applyAdd(UserContactApplyDto applyDto) {
        Integer curUid = ContextUtil.getUserInfo().getUid();

        // 获取申请人uid
        Integer applyUid = curUid < applyDto.getContactId() ? curUid : applyDto.getContactId();
        // 获取接收人uid
        Integer receiveUid = curUid > applyDto.getContactId() ? applyDto.getContactId() : curUid;

        // 添加联系人的uid
        if (Objects.equals(curUid, receiveUid) || Objects.equals(curUid, applyUid)) {
            throw new BusinessException("您无法添加自己为联系人");
        }

        // 查询接收人信息
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getUid, applyDto.getContactId());
        User receiveUser = userService.getOne(wrapper);
        if (Objects.isNull(receiveUser)) {
            throw new BusinessException("无法找到该用户，请检查你填写的账号是否正确。");
        }

        // 查询对方好友是否已经添加，如果已经拉黑无法添加
        UserContact userContact = userContactService.selectByUserIdAndContactId(applyUid, receiveUid);
        // 校验用户联系人状态，是否已添加，如果已拉黑，不能添加
        if (Objects.nonNull(userContact)) {
            if (Objects.equals(userContact.getIsBlocked(), UserContactBlockEnum.BLOCKED.getCode())) {
                // 相同，说明已经拉黑
                throw new BusinessException(Objects.equals(userContact.getBlockedBy(), applyUid) ? "您已拉黑对方" : "对方已将您拉黑");
            }

            // 如果联系人是当前用户删除的话，直接恢复联系人即可，不需要发送申请
            if (Objects.equals(userContact.getDeletedBy(), curUid)) {
                userContact.setContactStatus(UserContactStatus.FRIEND.getCode());
                userContactService.save(userContact);
            }
        }

        // 查询申请记录，如果已经申请过，则直接返回
        LambdaQueryWrapper<UserContactApply> applyWrapper = new LambdaQueryWrapper<>();
        applyWrapper
                .and(wp -> {
                        wp.eq(UserContactApply::getApplyUid, applyUid)
                                .or()
                                .eq(UserContactApply::getReceiveUid, receiveUid);
                });

        UserContactApply applyLog = this.getOne(applyWrapper);
        if (Objects.nonNull(applyLog)) {
            if (Objects.equals(applyLog.getStatus(), UserContactApplyStatus.APPLYING.getCode())) {
                // TODO 申请中的记录，如果添加的联系人不是申请人，可能需要发送事件通知前端更新
                if (Objects.equals(applyLog.getContactId(), applyDto.getContactId())) {
                    // 相同，说明已经申请过 可能需要发送事件通知前端更新
                    applyLog.setDeletedBy(0);
                    this.updateById(applyLog);
                    return;
                }

                // 不相同的情况下，更新contactid
                applyLog.setContactId(applyDto.getContactId());
                applyLog.setApplyTime(Instant.now().getEpochSecond());
                this.updateById(applyLog);
            } else {
                applyLog.setApplyTime(Instant.now().getEpochSecond());
                this.updateById(applyLog);
            }

            return;
        }

        // 不存在添加申请记录
        applyLog = new UserContactApply();
        applyLog.setApplyUid(applyUid);
        applyLog.setApplyDescription(applyUid.equals(applyDto.getContactId()) ? String.format("我是%s", receiveUser.getNickname()) :applyDto.getApplyInfo());
        applyLog.setReceiveUid(receiveUid);
        applyLog.setReceiveDescription(receiveUid.equals(applyDto.getContactId()) ? applyDto.getApplyInfo() : String.format("我是%s", receiveUser.getNickname()));
        applyLog.setContactType(UserContactTypeEnum.FRIEND.getCode());
        applyLog.setStatus(UserContactApplyStatus.APPLYING.getCode());
        applyLog.setContactId(applyDto.getContactId());
        applyLog.setApplyTime(Instant.now().getEpochSecond());
        this.save(applyLog);

        // TODO 添加权限记录
    }

    @Override
    public PageResultVo<UserContactVo> listContactApply(UserContactApplyQuery query) {

        Integer curUid = ContextUtil.getUserInfo().getUid();

        IPage page = new Page<>(query.getPindex(), query.getPsize());

        LambdaQueryWrapper<UserContactApply> wrapper = new LambdaQueryWrapper<>();

        // 下一页
        if (query.getId() != 0) {
            wrapper.gt(UserContactApply::getId, query.getId());
        }

        wrapper
                .and(wp -> {
                    wp.eq(UserContactApply::getApplyUid, curUid)
                            .or()
                            .eq(UserContactApply::getReceiveUid, curUid)
                            .or()
                            .eq(UserContactApply::getContactId, curUid);
                })
                .ne(UserContactApply::getDeletedBy, curUid)
                .orderBy(true, false, UserContactApply::getApplyTime)
                .orderBy(true, false, UserContactApply::getId);

        IPage<UserContactApply> applyPage = this.page(page, wrapper);
        PageResultVo<UserContactVo> resultVo = new PageResultVo<>();

        resultVo.setTotal(applyPage.getTotal());
        resultVo.setPindex(applyPage.getCurrent());
        resultVo.setPsize(applyPage.getSize());


        List<UserContactApply> list = applyPage.getRecords();
        AtomicReference<User> contactUser = new AtomicReference<>(new User());
        // 处理记录
        List<UserContactVo> collect = list.stream().map(item -> {
                    UserContactVo contactVo = new UserContactVo();

                    // 获取联系人id
                    Integer contactId = Objects.equals(item.getApplyUid(), curUid) ? item.getReceiveUid() : item.getApplyUid();
                    contactVo.setId(item.getId());
                    contactVo.setContactId(contactId);
                    contactVo.setApplyInfo(item.getApplyDescription());
                    contactVo.setStatus(item.getStatus());

                    // 查询联系人的头像，昵称信息
                    LambdaQueryWrapper<User> userQuery = new LambdaQueryWrapper<>();
                    userQuery.eq(User::getUid, contactId);
                    contactUser.set(userService.getOne(userQuery));

                    contactVo.setAvatar(contactUser.get().getAvatar());
                    contactVo.setNickname(contactUser.get().getNickname());

                    return contactVo;
                })
                .collect(Collectors.toList());

        resultVo.setList(collect);

        return resultVo;
    }


    /**
     * 申请通过添加好友
     * @param applyId
     */
    @Override
    public void dealWithApply(Integer applyId) {
        Integer uid = ContextUtil.getUserInfo().getUid();
        // 根据id查询申请记录
        UserContactApply applyInfo = this.getById(applyId);
        // 记录不存在，或者联系人id为自己
        if (Objects.isNull(applyInfo) ) {
            throw new BusinessException("记录不存在。");
        }

        if (Objects.equals(applyInfo.getContactId(), uid) ) {
            throw new BusinessException("接受失败。");
        }

        // 更新申请记录
        UserContactApply updateInfo = new UserContactApply();
        updateInfo.setStatus(UserContactApplyStatus.PASS.getCode());
        updateInfo.setApplyTime(Instant.now().getEpochSecond());
        updateInfo.setDeletedBy(0);

        LambdaQueryWrapper<UserContactApply> updateQuery = new LambdaQueryWrapper<>();
        updateQuery.eq(UserContactApply::getId, applyId)
                .eq(UserContactApply::getStatus, UserContactApplyStatus.APPLYING.getCode());

        this.update(updateInfo, updateQuery);


        // 查询用户联系人记录
        UserContact userContact = userContactService.selectByUserIdAndContactId(applyInfo.getApplyUid(), applyInfo.getReceiveUid());
        if (Objects.isNull(userContact)) {
            // 不存在，则新增联系人信息
            userContact = new UserContact();
            userContact.setUid(applyInfo.getApplyUid());
            userContact.setContactId(applyInfo.getReceiveUid());
            userContact.setContactType(UserContactTypeEnum.FRIEND.getCode());
            userContact.setContactStatus(UserContactStatus.FRIEND.getCode());
            userContact.setSource(UserContactSource.SEARCH.getCode());

            userContactService.save(userContact);
        } else {
            // 已经存在，判断状态
            if (Objects.equals(userContact.getContactStatus(), UserContactStatus.NOT_FRIEND.getCode())) {
                userContact.setContactStatus(UserContactStatus.FRIEND.getCode());
            }

            userContactService.updateById(userContact);
        }

        // TODO 新增会话消息
    }


}




